package com.pingan.generator.api.controller;

import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

import com.alibaba.fastjson.JSON;
import com.pingan.generator.api.entity.InterFaceInfo;
import com.pingan.generator.api.entity.mapper.ColInfoMapper;
import com.pingan.generator.api.entity.mapper.InterFaceMapper;
import com.pingan.generator.api.entity.util.GetFile;
import com.pingan.generator.api.service.GetService;
import com.pingan.generator.api.util.Constains;
import com.pingan.generator.api.util.SpringHelper;

@SuppressWarnings({"unchecked","rawtypes","unused"})
@Controller
public class GetController {

	@Autowired
	private SpringHelper springHelper;

	@Autowired
	private ColInfoMapper colInfoMapper;

	@Autowired
	private InterFaceMapper interFaceMapper;
	
	@Autowired
	private GetService getService;

	@RequestMapping(value = "/geturl", produces = "application/json; charset=utf-8")
	@ResponseBody
	public Object getMapPaths() {

		String result = "";
		RequestMappingHandlerMapping rmhp = springHelper.getObject(RequestMappingHandlerMapping.class);
		Map<RequestMappingInfo, HandlerMethod> map = rmhp.getHandlerMethods();
		List<List<?>> list = new ArrayList<List<?>>();
		String url = "";
		for (RequestMappingInfo info : map.keySet()) {
			Set<String> set = info.getPatternsCondition().getPatterns();
			url = set.toString().replace("[", "").replace("]", "");
			HandlerMethod hm = map.get(info);
			String methodName = hm.getMethod().getName();
			result = getMethodParams(hm.getBeanType(), methodName, list, url);
		}
		List<List> l = JSON.parseArray(result, List.class);
		for (int i = 0; i < l.size(); i++) {

			// 默认接口为修改接口
			boolean mark = false;

			long interFaceId = 0;
			InterFaceInfo faceInfo = new InterFaceInfo();
			faceInfo.setUrl(l.get(i).get(l.get(i).size() - 1).toString());

			InterFaceInfo info = interFaceMapper.getInfo(faceInfo.getUrl());
			if (info == null) {
				mark = true;
				// 保存接口
				faceInfo.setType(Constains.colType.ADD_COL);
				interFaceMapper.saveObject(faceInfo);
				interFaceId = faceInfo.getId();
			} else {
				interFaceId = info.getId();
				faceInfo.setId(interFaceId);
				faceInfo.setName(info.getName());

				String DBjson = JSON.toJSONString(info);
				String NEWjson = JSON.toJSONString(faceInfo);

				// 接口未发生变化
				if (DBjson.equals(NEWjson)) {
					System.out.println("接口url及内容未发生变化,再对比接口里面字段是否变化");
					// 如果只有出参或者只有入参 或者都没有
					if (l.get(i).size() == 3) {
						getService.updateList(l.get(i).get(1).toString(), interFaceId, 0, mark);
					} else if (l.get(i).size() == 1) {
						continue;
					}

					String mapString2 = l.get(i).get(0).toString();
					getService.updateList(mapString2, interFaceId, 0, mark);
				} else {

					Map<String, Object> para = new HashMap<String, Object>();
					para.put("interfaceId", interFaceId);

					// 接口发生变化更新新接口(保存新的接口)
					faceInfo.setType(Constains.interfaceType.ADD_INTERFACE);
					interFaceMapper.saveObject(faceInfo);

					// 更新旧的接口为移除状态
					para.put("type", Constains.interfaceType.REMOVE_INTERFACE);
					interFaceMapper.updateStatus(para);

					// 移除当前接口下所有字段状态修改为移除
					para.put("type", Constains.colType.REMOVE_COL);
					colInfoMapper.updateStatus(para);
				}
			}
			if (mark) {
				// 如果只有出参或者只有入参 或者都没有
				if (l.get(i).size() == 3) {
					// 入参保存
					getService.saveList(l.get(i).get(1).toString(), interFaceId, 0, mark);
				} else if (l.get(i).size() == 1) {
					continue;
				}

				String mapString2 = l.get(i).get(0).toString();
				getService.saveList(mapString2, interFaceId, 0, mark);

				System.out.println(l.get(i).get(l.get(i).size() - 1).toString() + "下个接口见。。。。。。。。。。。。。。。。");
			}

		}
		return l;
	}
	
	

	/**
	 * @param cla
	 *            类名  *
	 * @param methodNameTemp
	 *            方法名  *
	 * @return 该方法的声明部分 功能：返回一个方法的声明部分，包括参数类型和参数名  
	 */
	private String getMethodParams(Class<?> cla, String methodNameTemp, List<List<?>> list, String url) {
		try {
			Method[] methods = cla.getMethods();
			for (Method method : methods) {
				// 存储字段 以及url
				List<String> colListRes = new ArrayList<String>();
				String methodName = method.getName();
				if (methodNameTemp.equals(methodName)) {
					Type returnType = method.getGenericReturnType();// 返回值类型
					if (returnType instanceof ParameterizedType) {
						Type[] genericTypes = ((ParameterizedType) returnType).getActualTypeArguments();
						Map<String, Object> resp = null;
						for (Type genericType : genericTypes) {
							String name = genericType.getTypeName();
							if (name.contains("java.util.Map")) {
								continue;
							}
							resp = getMap(name, resp, Constains.isReqOrResp.IS_RESP, url);// name返回值类型名，resp
							// map,2输出参数，url：controller-url
							colListRes.add(JSON.toJSONString(resp));
						}
					}
				}

				// 入参
				Map<String, Object> req = null;
				Class<?>[] parameterTypes = method.getParameterTypes();
				if (methodNameTemp.equals(methodName)) {
					for (Class<?> clas : parameterTypes) {
						if (clas.toString().indexOf("HttpServletRequest") != -1 || clas.toString().indexOf("HttpServletResponse") != -1) {
							continue;
						}
						System.out.println(clas.toString());
						String parameterName = clas.getTypeName();
						req = getMap(parameterName, req, Constains.isReqOrResp.IS_REQ, url);
						colListRes.add(JSON.toJSONString(req));
					}
				}
				if (colListRes != null && colListRes.size() != 0) {
					colListRes.add(url);
					list.add(colListRes);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return JSON.toJSONString(list);
	}

	/**
	 * 
	 * @param name
	 *            出入参参数对象名称
	 * @param r
	 * @param url
	 * @return
	 * @throws ClassNotFoundException
	 */
	private Map<String, Object> getMap(String name, Map<String, Object> r, String type, String url)
			throws ClassNotFoundException {
		// 如果包含泛型
		if (name.contains("<")) {// List<Object>
			r = GetFile.getFileds(Class.forName(name.substring(0, name.indexOf("<"))), new HashMap<String, Object>(),
					name.substring(name.indexOf("<") + 1, name.lastIndexOf(">")), type, url);
		} else {
			// 非泛型
			r = GetFile.getFileds(Class.forName(name), new HashMap<String, Object>(), null, type, url);
		}
		return r;
	}




}
